<?php

/**
 * Pago form.
 *
 * @package    AltargetEcommerce
 * @subpackage form
 * @author     Carlo Lopez
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class PagoForm extends BasePagoForm
{
  // las entregas que se deben despachar luego de comprobar el pago
  //protected $entregas = array();

  // los paquetes que se solicitan para comprar
  protected $paquetes = array();

  protected $usuario;

  public function configure()
  {
      
    unset(
      $this['created_at'], $this['updated_at'], $this['efectuado'], $this['cliente_id'], $this['monto']
    );

    $validators = array(
      'nombre'   => new sfValidatorString(array('required' => true, 'max_length' => 64)),
      'numero_tarjeta' => new altargetValidatorNumeroTC(),
//      'vencimiento'   => new sfValidatorDate(array('date_format' => '~(?P<month>\d{2})/(?P<year>\d{4})~',
//                                                   'date_output' => '%day%-%month%-%year%'
//                                             )),
      'vencimiento'   => new sfValidatorDate(),
      'codseguridad' => new sfValidatorString(array('required' => true, 'min_length' => 3, 'max_length' => 4)),
    );

    $widget = new sfWidgetFormDate(array(
        'format' => '%month%/%year%',
        'years'  => array(
                      '2012' => '2012',
                      '2013' => '2013',
                      '2014' => '2014',
                      '2015' => '2015',
                      '2016' => '2016',
                      '2017' => '2017',
                      '2018' => '2018',
                      '2019' => '2019',
                      '2020' => '2020',
                      '2021' => '2021',
                      '2022' => '2022',
                    ),
        'can_be_empty' => false,
    ));

    $this->widgetSchema['vencimiento'] = $widget;

    foreach($validators as $nombre => $validator)
      $this->validatorSchema[$nombre] = $validator;

/*    $this->validatorSchema->setPostValidator(
      new sfValidatorCallBack(array('callback' => array($this, 'checkNumeroTarjetaValido')))
    );
*/
    $widget = $this->getWidget('nombre');
    $widget->setLabel('Nombre del Titular');
    $widget->setAttribute('autocomplete', 'off');
    
    $widget = $this->getWidget('codseguridad');
    $widget->setLabel('Codigo de Seguridad');
    $widget->setAttribute('autocomplete', 'off');
    
    $widget = $this->getWidget('numero_tarjeta');
    $widget->setLabel('Numero de Tarjeta');
    $widget->setAttribute('autocomplete', 'off');
    
    
  }

  /*
   * Verifica que los datos de la tarjeta de credito sean correctos.
   *
   * TODO: aqui va parte de la integracion con los API del MERCHANT GATEWAY.
   *       Para ver un ejemplo de uso de los valores ($values) que se deben manipular, ir a
   *       HOME_DIR/lib/form/MyaltargetPricingRequestForm.class.php
   *
   */
  protected function checkNumeroTarjetaValido($validator, $values)
  {
    /*
    if(  )
    {
      throw new sfValidatorError($validator, 'Datos de Tarjeta de Credito Invalidos');

    }
    */
    

    return $values;
  }

  /**
   * En caso de que se hubiera pre-solicitado antes un cobro al gateway, justificado como pago
   * de un cliente a las productos que hubiere solicitado, entonces se genera una orden de
   * despacho asociada al cliente, y se almacena aquel pago, pendiente para ser cobrado.
   *
   */
  protected function doSave($con = null)
  {
    if(null === $con)
    {
      $con = $this->getConnection();
    }

    //se actualiza el pago 	
    $this->updateObject();
    //$pago = $this->getObject()->save($con);
    $this->saveEmbeddedForms($con);

    
    //se crea un cliente asociado al usuario, en caso de no existir ya
    //$cliente = null;
    //if( $this->usuario->esCliente() )


    $cliente = $this->usuario->getGuardUser()->getCliente();
  
    if( !$this->usuario->getGuardUser()->Cliente->exists()) 
    {
      $cliente = new Cliente();
      $cliente->fromUsuario($this->usuario->getGuardUser());
      $cliente->save();
      $this->usuario->getGuardUser()->link('Cliente', $cliente->getPrimaryKey());
      $this->usuario->getGuardUser()->save();
    }

    $this->getObject()->setEfectuado(false); 
    $this->getObject()->link('Cliente', $cliente->getPrimaryKey());
    $this->getObject()->save();  

    $entregas = array();
    foreach($this->paquetes as $paquete)
    {
      $clasentreg = 'Entrega' . ucfirst(strtolower($paquete->getProducto()->getNombre()));
      if(class_exists($clasentreg))
      {
        for( $i = 0; $i < $paquete->getFrecuencia()->getCantidadMeses() ; $i++)
        {
          $entrega = new $clasentreg();
          $entrega->fromPaquete($paquete);
          $entrega->setEntregado(false); 
          array_push($entregas, $entrega);
          $paquete->setEntrega($entrega);
        }
      }
    }
    //  }
    foreach($entregas as $key => $entrega)
    {
       /* TODO: casos en que el cliente ya estuviera afiliado
          - afiliado y solvente => si se cambia a un plan de menor precio no es necesario pagar
          - afiliado y no solvente => debe pagar
          - no afiliado => debe pagar
       */

      // en caso de modificacion de afiliacion
      /*
      if( $cliente->estaAfiliado($entrega->getProducto()) 
          && Afiliacion::SOLVENTE === ($afiliacion = $cliente->getAfiliacion($entrega->getProducto()))->getStatus )
      {
        // si el precio de la afiliacion actual es mayor o igual a la que resulte de la modificacion
        if( ($precio_afil_actual = $afiliacion->getPrecio) >= ($precio_nueva_afil = $entrega->getPrecio()) )
        {

        }
        else
          

        $orden = new OrdenInstalar($cliente, $entrega, $this->getObject());
        $orden->save();
      } 
      
      
      else // si no esta afiliado o no esta solvente debe pagar 
      */
  
      $this->getObject()->setMonto($this->getObject()->getMonto() + $entrega->getCosto());
      //$entrega->save();

  //    $meses = $entrega->getFrecuencia()->getCantidadMeses();
  //    for($i = 0; $i < $meses; $i++)
  //    {
        $orden = new OrdenInstalar();
    
        $afiliacion = null;
        if( $entrega->seTieneAfiliado($cliente) )
        {
          if( $cliente->estaSolvente($entrega->getProductoId()) )
          {

            $orden = new OrdenActualizar();
            $orden->setDespachoInmediato(false);
            //if(!isset($fecha))
            $fecha = Doctrine_Core::getTable('Orden')
                       ->getSiguienteFechaDespacho($cliente->getPrimaryKey(), $entrega->getProductoId()); 
            $orden->setFechaDespacho($fecha->dump());
            $afiliacion = Doctrine_Core::getTable('Afiliacion')
                            ->findOneByProductoIdAndClienteId($entrega->getProductoId(),$cliente->getPrimaryKey());
            
  //          $fecha = new sfDate(sfTime::addMonth(sfDateTimeToolkit::getTS($fecha), 1));
            
          }
        } else {
          //configuracion de la afiliacion
          $afiliacion = new Afiliacion();
          $afiliacion->setClienteId($cliente->getPrimaryKey());
          $afiliacion->setProductoId($entrega->getProductoId());
          $afiliacion->setFrecpagoId($entrega->getFrecuenciaId());
          //$afiliacion->setFechaCorte(new sfDate());
          $afiliacion->setActiva(true);
          $afiliacion->save();

        }

        $orden->setClienteId($cliente->getPrimaryKey());
        $orden->setPagoId($this->getObject()->getPrimaryKey());
        $orden->setStatus(Orden::A_CONFIRMAR); 
      
        $orden->save();
  //    }

      //$orden->link('Entrega', array($entrega->getPrimaryKey()));
      //$entrega->link('Orden', array($orden->getPrimaryKey()));
      $entrega->setOrdenId($orden->getPrimaryKey());
      $entrega->save();

    }

    $this->getObject()->save();

  }


/**
  TODO: 

  En caso de que la solicitud de cobro sea confirmada entonces form->save():

  salvar el form en este caso implica salvar el pago como no cobrado,
  salvar cada entrega, salvar una orden de despacho por cada entrega,
  y salvar un cliente desactivado.

  TODO end 
 
 */


  /**
   * Se solicitan paquetes para ser despachados a un usuario.
   *
   * @param array<Paquete> $paquetes Los paquetes a solicitar.
   *
   * @return array       devuelve un arreglo con la primera casilla
   *                     conteniendo una respuesta y la segunda un mensaje del gateway.
   * @throws sfException Si ocurre error en la solicitud de cobro, o si ocurre error creando 
   *                     la entree error en la solicitud de cobro, o si ocurre error creando 
   *                     la entrega.
   */
  public function solicitarPaquetes($paquetes = array(), sfGuardSecurityUser $usuario)
  {
    $this->paquetes = array();
    $this->usuario = $usuario;
    //$solicefectiva = ProcesamPagos::solicitarCobro($this->getObject(), $paquetes);
    // recibe la respuesta del banco
    $solicefectiva = true; //suponiendo que la cosa funciono

    if($solicefectiva)
    {

      $this->paquetes = $paquetes;

      $this->doSave();
      
    }
    else
      throw new sfException('Error en la presolicitud de cobro');
  }


}
